package com.agrm.stmq.service.impl;
import com.agrm.api.client.OrderClient;
import com.agrm.model.common.dtos.ResponseResult;
import com.agrm.model.order.dto.OrderSubmit;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.time.Duration;

@RocketMQMessageListener(
        topic = "stmall-order-topic",
        consumerGroup = "g3",
        consumeTimeout = 30, // 设置消费超时时间
        maxReconsumeTimes = 3 // 最大重试次数
)@Service
public class OrderConsumeServiceImpl implements RocketMQListener<OrderSubmit> {
    private RedisTemplate<String, Object> redisTemplate;
    private OrderClient orderClient;
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }


    //监听到消息队列的消息，即秒杀订单
    @Override
    public void onMessage(OrderSubmit orderSubmit) {
        String seckillNo = orderSubmit.getSeckillNo();
        String redisKey = "seckill-order:" + seckillNo;

        // 更严格的幂等性检查
        if (Boolean.TRUE.equals(redisTemplate.hasKey(redisKey))) {
            System.out.println("订单已处理，跳过重复消费，seckillNo: " + seckillNo);
            return;
        }

        Integer goodId = orderSubmit.getCartGoods().getGoods().get(0).getId();

        try {
            // 先设置处理中状态，防止并发
            Boolean lockAcquired = redisTemplate.opsForValue().setIfAbsent(
                    redisKey + ":processing", "1", Duration.ofSeconds(30)
            );

            if (Boolean.FALSE.equals(lockAcquired)) {
                System.out.println("订单正在处理中，跳过，seckillNo: " + seckillNo);
                return;
            }

            ResponseResult<Boolean> save = orderClient.save(orderSubmit);
            boolean data = save.getData();

            if (data) {
                // 订单创建成功，设置永久标记（根据业务需求调整过期时间）
                redisTemplate.opsForValue().set(redisKey, "SUCCESS", Duration.ofDays(1));
                this.rocketMQTemplate.syncSendDelayTimeSeconds("shoplook2025-orderseckill-check", orderSubmit.getSeckillNo(), 15*60);
            } else {
                // 订单创建失败
                redisTemplate.opsForValue().set(redisKey, "FAILED", Duration.ofMinutes(30));
            }

        } catch (Exception e) {
            // 不再抛出异常，避免重试
            System.err.println("订单处理异常，seckillNo: " + seckillNo + ", 错误: " + e.getMessage());
            // 标记为失败，并回滚库存
            redisTemplate.opsForValue().set(redisKey, "FAILED", Duration.ofMinutes(30));
            redisTemplate.opsForValue().increment("seckill-stock:" + goodId, 1);

            // 记录详细日志，但不抛出异常
            e.printStackTrace();
        } finally {
            // 清理处理中锁
            redisTemplate.delete(redisKey + ":processing");
        }
    }

    @Autowired
    public void setOrderClient(OrderClient orderClient) {
        this.orderClient = orderClient;
    }

    @Autowired
    public void setRocketMQTemplate(RocketMQTemplate rocketMQTemplate) {
        this.rocketMQTemplate = rocketMQTemplate;
    }
}
